#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
#include <iomanip>
#include <cblas.h>
#include <lapacke.h>
#include "Spline.hpp"
#include "Curvefitting.hpp"
#define PI 3.14159265358979323846

class Fx : public Function {
public:
    double operator() (double t) const override {
        return 16 * pow(sin(t), 3);
    }
};

class Fy : public Function {
public:
    double operator() (double t) const override {
        return 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t);
    }
};

void generate_and_save_fitting(int n, const std::string &filename) {
    std::vector<double> X(n + 1);
    std::vector<double> Y(n + 1);
    std::vector<double> T(n + 1);
    Fx fx;
    Fy fy;

    // Generate the points for the heart curve
    for (int i = 0; i <= n; ++i) {
        T[i] = 2 * i * PI / n;
        X[i] = fx(T[i]);
        Y[i] = fy(T[i]);
    }

    // Perform curve fitting using cumulative chord length
    auto result = Curve_Fitting_cumulativechordal_length(X, Y, T);

    // Extract the resulting spline points
    const std::vector<double>& x_spline = result[0];
    const std::vector<double>& y_spline = result[1];

    // Save the resulting fitted spline points to a file
    std::ofstream file(filename);
    if (file.is_open()) {
        for (size_t i = 0; i < x_spline.size(); ++i) {
            file << x_spline[i] << ", " << y_spline[i] << std::endl;
        }
        file.close();
        std::cout << "Fitted spline points saved to " << filename << std::endl;
    } else {
        std::cerr << "Failed to open file " << filename << std::endl;
    }
}

int main() {
    // Perform fitting for N = 10, 40, 160
    generate_and_save_fitting(10, "E1_fitted_spline_N10.txt");
    generate_and_save_fitting(40, "E1_fitted_spline_N40.txt");
    generate_and_save_fitting(160, "E1_fitted_spline_N160.txt");
    return 0;
}

